﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;

namespace Win.CSharp.JSONFormatter
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_convert_Click(object sender, EventArgs e)
        {
            JObject j = JObject.Parse(txt_json.Text);
            txt_code.Text = ProgressObject(j);
        }

        private string ProgressObject(JToken j)
        {
            string code = "";
            foreach (JToken v in j)
            {
                string varName = "";
                switch (v.Type)
                {
                    case JTokenType.Object:
                    {
                        code = code + this.ProgressObject(v);
                        continue;
                    }
                    case JTokenType.Array:
                    {
                        code = code + this.ProgressObject(v);
                        continue;
                    }
                    case JTokenType.Property:
                        switch (((JProperty) v).Value.Type)
                        {
                            case JTokenType.Object:
                                varName = ((JProperty) v).Name;
                                code += "public class c" + varName + "{\r\n";
                                code += this.ProgressObject(((JProperty) v).Value);
                                code += "}\r\n";
                                code += String.Format("public c{0} {{get;set;}}\r\n", varName);
                                break;
                            case JTokenType.Array:
                                varName = ((JProperty) v).Name;
                                if (((JProperty) v).Value.Any<JToken>())
                                {
                                    if (((JProperty) v).Value.First.Type == JTokenType.Object)
                                    {
                                        code += "public class c" + varName + "{\r\n";
                                        code += this.ProgressObject(((JProperty) v).Value.First);
                                        code += "}\r\n";
                                        code += String.Format("private List<c{0}> _{0};\r\n", varName);
                                        code +=
                                            String.Format(
                                                "public List<c{0}> {0} {{get {{return _{0};}} set {{ _{0} = value;}}}}\r\n",
                                                varName);
                                    }
                                }
                                else
                                {
                                    code = code + "private object[] _" + varName + ";\r\n";
                                    code = code +
                                           string.Format(
                                               "public object[] {0} {{get {{return _{0};}} set {{ _{0} = value;}}}}\r\n",
                                               varName);
                                }
                                break;
                            case JTokenType.Integer:
                                varName = ((JProperty) v).Name;
                                code = code + "public int " + varName + "{get;set;}\r\n";
                                break;

                            case JTokenType.Float:
                                varName = ((JProperty) v).Name;
                                code = code + "public float " + varName + "{get;set;}\r\n";
                                break;
                            case JTokenType.String:
                                varName = ((JProperty) v).Name;
                                code = code + "public string " + varName + "{get;set;}\r\n";
                                break;
                            case JTokenType.Boolean:
                                varName = ((JProperty) v).Name;
                                code = code + "public bool " + varName + "{get;set;}\r\n";
                                break;
                        }
                        break;
                }
            }
            return code;
        }

        private void txt_code_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.Modifiers == Keys.Control) && (e.KeyCode == Keys.A))
            {
                ((TextBox)sender).SelectAll();
            }
        }

        private void txt_json_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.Modifiers == Keys.Control) && (e.KeyCode == Keys.A))
            {
                ((TextBox)sender).SelectAll();
            }
        }
    }
}
